package cn.com.open.ms.ecgpaasdatarest.dynamicconfig;

import cn.com.open.ms.ecgpaasdatarest.databasemodel.DataBaseSource;
import cn.com.open.ms.ecgpaasdatarest.service.AppService;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Properties;

/**
 * @Description TODO
 * @Author 奶茶
 * Created by on 2018/11/26 12:15.
 */
@Component
public class SwitchDataSource {

    private static final Logger logger = LoggerFactory.getLogger(SwitchDataSource.class);

    @Autowired
    private AppService appService;

    /**
     * 动态加载数据源
     * @param appKey
     * @param businessName
     * @return
     */
    public DruidDataSource dynamicSwitchDataBase(String appKey,String businessName){
        DruidDataSource druidDataSource = new DruidDataSource();
        Map<Object, Object> dataSourceMap = DynamicDataBaseSource.getInstance().getDataSourceMap();
        try {
            if(!dataSourceMap.containsKey(businessName)){
                DataBaseSource dataSourceInfo = appService.getDataSourceInfo(appKey, businessName);
                druidDataSource = createDataSource(dataSourceInfo);
                dataSourceMap.put(businessName,druidDataSource);
                DynamicDataBaseSource.getInstance().setTargetDataSources(dataSourceMap);
            }else {
                druidDataSource = (DruidDataSource) dataSourceMap.get(businessName);
            }
        } catch (Exception e) {
            logger.error("创建数据源异常：",e);
        }
        DBContextHolder.setDbType(businessName);
        return druidDataSource;
    }

    /**
     * 创建动态数据源对象
     * @param dataBaseInfo
     * @return
     */
    private DruidDataSource createDataSource(DataBaseSource dataBaseInfo) throws Exception {

        Properties properties = new Properties();

        properties.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, dataBaseInfo.getDriver());
        properties.put(DruidDataSourceFactory.PROP_URL, dataBaseInfo.getUrl());
        properties.put(DruidDataSourceFactory.PROP_USERNAME, dataBaseInfo.getUsername());
        properties.put(DruidDataSourceFactory.PROP_PASSWORD, dataBaseInfo.getPassword());

        properties.put(DruidDataSourceFactory.PROP_INITIALSIZE,dataBaseInfo.getInitialSize().toString());
        properties.put(DruidDataSourceFactory.PROP_MAXACTIVE,dataBaseInfo.getMaxActive().toString());
        properties.put(DruidDataSourceFactory.PROP_MINIDLE,dataBaseInfo.getMinIdle().toString());
        properties.put(DruidDataSourceFactory.PROP_MAXWAIT,dataBaseInfo.getMaxWait().toString());
        properties.put(DruidDataSourceFactory.PROP_MINEVICTABLEIDLETIMEMILLIS,dataBaseInfo.getMinEvictableIdleTimeMillis().toString());
        properties.put(DruidDataSourceFactory.PROP_POOLPREPAREDSTATEMENTS,dataBaseInfo.getPoolPreparedStatements().toString());
        properties.put(DruidDataSourceFactory.PROP_MAXOPENPREPAREDSTATEMENTS,dataBaseInfo.getMaxOpenPreparedStatements().toString());
        properties.put(DruidDataSourceFactory.PROP_VALIDATIONQUERY,"SELECT 1");
        properties.put(DruidDataSourceFactory.PROP_VALIDATIONQUERY_TIMEOUT,"30000");
        properties.put(DruidDataSourceFactory.PROP_TESTWHILEIDLE,"true");
        properties.put(DruidDataSourceFactory.PROP_TESTONBORROW,"false");
        properties.put(DruidDataSourceFactory.PROP_TESTONRETURN,"false");


        DruidDataSource dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        dataSource.setUseUnfairLock(true);

        return dataSource;
    }

}
